// Fill out your copyright notice in the Description page of Project Settings.


#include "ListUIStyle.h"
#include "Styling/SlateStyleRegistry.h"
#include "Slate/SlateGameResources.h"
#include "Brushes/SlateImageBrush.h"
#include "Engine/Font.h"
#include "Styling/StyleColors.h"

TSharedPtr<FSlateStyleSet> ListUIStyle::StyleInstance = nullptr;
TMap<FString, UFont*> ListUIStyle::CustomFont = TMap<FString, UFont*>();
TMap<FString, FSlateBrush*> ListUIStyle::CustomFSlateBrush = TMap<FString, FSlateBrush*>();
TMap<FString, FButtonStyle*> ListUIStyle::CustomButtonStyle = TMap<FString, FButtonStyle*>();
TMap<FString, FCheckBoxStyle*> ListUIStyle::CustomCheckBoxStyle = TMap<FString, FCheckBoxStyle*>();
TMap<FString, FTextBlockStyle*> ListUIStyle::CustomSlateFontInfo = TMap<FString, FTextBlockStyle*>();
//高斯模糊值
uint16 ListUIStyle::BlurValue = 100; //0-100  0是不模糊
//背景颜色
FLinearColor ListUIStyle::DialogColor = FLinearColor(1, 1, 1, 1);
uint16 ListUIStyle::WindowShadowWidth = 74;
//窗口背景框阴影高
uint16 ListUIStyle::WindowShadowHigh = 74;
uint16 ListUIStyle::WindowLeftShadowWidth = 37; //左侧的阴影边距
uint16 ListUIStyle::WindowTopShadowHigh = 27; //顶部的阴影边距
FSliderStyle* ListUIStyle::SliderStyle = nullptr;


void ListUIStyle::InitResource()
{
	InitFont(); //初始化所有的字体
	InitImage(); //初始化所有的图片资源
	InitButtonStyle(); //初始化所有的按钮央视
	InitCheckBoxStyle(); //初始化所有的单选框
	InitOtherStyle(); //初始化其他
}

//添加所有图片
void ListUIStyle::InitImage()
{
	CustomFSlateBrush.Empty();
	//一默认的方式加载/Game/ListLibraryUI/Img下的所有图片
	LoadAllImage();
	//实线矩形
	AddImage(TEXT("/Game/ListLibraryUI/img/WarningLine.WarningLine"),TEXT("WarningLine"), ESlateBrushDrawType::Type::Box,
			 FMargin(0.1, 0.0, 0.0, 0.1), ESlateBrushTileType::Type::NoTile,
			 ESlateBrushImageType::Type::FullColor, FVector2D(379, 10), FSlateColor(FLinearColor(1, 1, 1, 1)));
}

//加载所有的图片
void ListUIStyle::LoadAllImage()
{
	TArray<FString> AllFile;
	IFileManager& FileManager = IFileManager::Get();
	FString FinalPath = FPaths::ProjectContentDir() + "ListLibraryUI/img/*";
	FileManager.FindFiles(AllFile, *FinalPath, true, true);

	for (int i = 0; i < AllFile.Num(); i++)
	{
		FString FileName;
		FString FileType;
		//以.为分隔符
		AllFile[i].Split(".", &FileName, &FileType, ESearchCase::Type::CaseSensitive, ESearchDir::Type::FromEnd);
		if (FileName.Len() > 0 && !FileType.Compare("uasset"))
		{
			FString ImagePath = FString::Printf(TEXT("/Game/ListLibraryUI/img/%s.%s"), *FileName, *FileName);
			UTexture2D* GridTexture = LoadObject<UTexture2D>(nullptr, *ImagePath, nullptr, LOAD_None, nullptr);
			if (GridTexture == nullptr)
				continue;
			GridTexture->AddToRoot(); //防止资源释放
			FSlateBrush* SlateBrush = new FSlateBrush();
			SlateBrush->SetResourceObject(GridTexture); //资源
			SlateBrush->SetImageSize(FVector2D(GridTexture->GetSizeX(), GridTexture->GetSizeY())); //尺寸
			/*SlateBrush->TintColor = FSlateColor(FLinearColor(1, 1, 1, 1)); //颜色
			SlateBrush->Tiling = ESlateBrushTileType::Type::NoTile; //平铺类型
			SlateBrush->DrawAs = ESlateBrushDrawType::Type::Image; //
			SlateBrush->Margin = FMargin(0, 0, 0, 0); //对应的平铺边距*/
			//如果已经存在则释放资源
			if (CustomFSlateBrush.Contains(FileName))
			{
				FSlateBrush* DeleteBrush = CustomFSlateBrush[FileName];
				delete(DeleteBrush);
				CustomFSlateBrush.Remove(FileName);
			}
			//加入到表中
			CustomFSlateBrush.Add(FileName, SlateBrush);
		}
	}
}

void ListUIStyle::InitButtonStyle()
{
	CustomButtonStyle.Empty();
	FButtonStyle* ButtonStyle = nullptr;
	//透明风格按钮
	ButtonStyle = new FButtonStyle();
	ButtonStyle->SetNormal(FSlateNoResource());
	ButtonStyle->SetHovered(FSlateNoResource());
	ButtonStyle->SetPressed(FSlateNoResource());
	/*ButtonStyle->SetNormalPadding( FMargin(0,0) );
	ButtonStyle->SetPressedPadding( FMargin(0,0) );*/
	CustomButtonStyle.Add("transparencyStyle", ButtonStyle);
	ButtonStyle = new FButtonStyle();
	ButtonStyle->SetNormal(FSlateNoResource());
	ButtonStyle->SetHovered(*CustomFSlateBrush["CalendarHover"]);
	ButtonStyle->SetPressed(FSlateBoxBrush("", FMargin(0), FLinearColor(0, 0.44, 1, 0.5)));
	CustomButtonStyle.Add("CalendarStyle", ButtonStyle);

	//圆角三态按钮风格
	ButtonStyle = new FButtonStyle();
	ButtonStyle->SetNormal(*GetTempImage(TEXT("/Game/ListLibraryUI/img/ButtonDefault_small.ButtonDefault_small"),TEXT("ButtonDefault_small"), ESlateBrushDrawType::Type::Box,
										 FMargin(0.4, 0.4, 0.4, 0.4), ESlateBrushTileType::Type::NoTile,
										 ESlateBrushImageType::Type::FullColor, FVector2D(26, 26), FSlateColor(FLinearColor(1, 1, 1, 1))));
	ButtonStyle->SetHovered(*GetTempImage(TEXT("/Game/ListLibraryUI/img/SmallButtonSelect.SmallButtonSelect"),TEXT("SmallButtonSelect"), ESlateBrushDrawType::Type::Box,
										  FMargin(0.4, 0.4, 0.4, 0.4), ESlateBrushTileType::Type::NoTile,
										  ESlateBrushImageType::Type::FullColor, FVector2D(26, 26), FSlateColor(FLinearColor(1, 1, 1, 1))));
	ButtonStyle->SetPressed(*GetTempImage(TEXT("/Game/ListLibraryUI/img/SmallButtonSelect.SmallButtonSelect"),TEXT("SmallButtonSelect"), ESlateBrushDrawType::Type::Box,
										  FMargin(0.4, 0.4, 0.4, 0.4), ESlateBrushTileType::Type::NoTile,
										  ESlateBrushImageType::Type::FullColor, FVector2D(26, 26), FSlateColor(FLinearColor(0.069, 0.436, 1, 1))));
	CustomButtonStyle.Add("FilletAngleButtonStyle", ButtonStyle);
}

FCheckBoxStyle* ListUIStyle::GetCheckBoxStyle(FString CheckBoxStyleName)
{
	if (CustomCheckBoxStyle.Contains(CheckBoxStyleName.ToLower()))
	{
		return CustomCheckBoxStyle[CheckBoxStyleName.ToLower()];
	}
	else
	{
		return nullptr;
	}
}

bool ListUIStyle::UpdateCheckBoxStyle(FString CheckBoxStyleName, FCheckBoxStyle* CheckBoxStyle)
{
	if (CustomCheckBoxStyle.Contains(CheckBoxStyleName.ToLower()))
	{
		CustomCheckBoxStyle[CheckBoxStyleName.ToLower()] = CheckBoxStyle;
		return true;
	}
	return false;
}

FButtonStyle* ListUIStyle::GetButtonStyle(FString ButtonStyleName)
{
	if (CustomButtonStyle.Contains(ButtonStyleName.ToLower()))
	{
		return CustomButtonStyle[ButtonStyleName.ToLower()];
	}
	else
	{
		return nullptr;
	}
}

bool ListUIStyle::UpdateButtonStyle(FString ButtonStyleName, FButtonStyle* ButtonStyle)
{
	if (CustomButtonStyle.Contains(ButtonStyleName.ToLower()))
	{
		CustomButtonStyle[ButtonStyleName.ToLower()] = ButtonStyle;
		return true;
	}
	return false;
}

bool ListUIStyle::UpdataImageStyle(FString ImageName, FSlateBrush* style)
{
	if (CustomFSlateBrush.Contains(ImageName.ToLower()))
	{
		CustomFSlateBrush[ImageName.ToLower()] = style;
		return true;
	}
	return false;
}

void ListUIStyle::InitCheckBoxStyle()
{
	CustomCheckBoxStyle.Empty();
}

void ListUIStyle::InitOtherStyle()
{
	//进度条
	SliderStyle = new FSliderStyle();
	SliderStyle->SetNormalBarImage(FSlateRoundedBoxBrush(FLinearColor(0.01,0.32,1.0), FVector2D(16,8)))
		   .SetHoveredBarImage(FSlateRoundedBoxBrush(FLinearColor(0.01,0.32,1.0), FVector2D(16,8)))
		   .SetDisabledBarImage(FSlateRoundedBoxBrush(FLinearColor(0.01,0.32,1.0), FVector2D(16,8)))
		   .SetNormalThumbImage(FSlateRoundedBoxBrush(FLinearColor(0.01,0.32,1.0), FVector2D(16,8)))
		   .SetHoveredThumbImage(FSlateRoundedBoxBrush(FLinearColor(0.01,0.32,1.0), FVector2D(16,8)))
		   .SetDisabledThumbImage(FSlateRoundedBoxBrush(FLinearColor(0.01,0.32,1.0), FVector2D(16,8)))
		   .SetBarThickness(1.f);
	
	/*SliderStyle->SetNormalBarImage(*CustomFSlateBrush["HorScroll"])
	           .SetHoveredBarImage(*CustomFSlateBrush["HorScroll"])
	           .SetDisabledBarImage(*CustomFSlateBrush["HorScroll"])
	           .SetNormalThumbImage(*CustomFSlateBrush["HorScroll"])
	           .SetHoveredThumbImage(*CustomFSlateBrush["HorScroll"])
	           .SetDisabledThumbImage(*CustomFSlateBrush["HorScroll"])
	           .SetBarThickness(1.f);*/
}

FString ListUIStyle::FLinearColorToFString(FLinearColor InColor)
{
	int R = InColor.R * 0xFF;
	int G = InColor.G * 0xFF;
	int B = InColor.B * 0xFF;
	int A = InColor.A * 0xFF;
	return FString::Printf(TEXT("%02X%02X%02X%02X"), R, G, B, A);
}

FLinearColor ListUIStyle::FStringToFLinearColor(FString strColor)
{
	return FLinearColor(FColor::FromHex(strColor));
}

//添加一个图片资源
void ListUIStyle::AddImage(FString Path, const FString Name, ESlateBrushDrawType::Type InDrawType, const FMargin& InMargin, ESlateBrushTileType::Type InTiling, ESlateBrushImageType::Type InImageType, const FVector2D& InImageSize, const FSlateColor& InTint)
{
	UTexture2D* GridTexture = LoadObject<UTexture2D>(nullptr, *Path, nullptr, LOAD_None, nullptr);
	GridTexture->AddToRoot(); //防止资源被释放
	FSlateBrush* SlateBrush = new FSlateBrush();
	SlateBrush->SetResourceObject(GridTexture); //资源
	SlateBrush->SetImageSize(InImageSize); //尺寸
	SlateBrush->TintColor = InTint; //颜色
	SlateBrush->Tiling = InTiling; //平铺类型
	SlateBrush->DrawAs = InDrawType; //
	SlateBrush->Margin = InMargin; //对应的平铺边距
	//如果已经存在则释放资源
	if (CustomFSlateBrush.Contains(Name))
	{
		FSlateBrush* DeleteBrush = CustomFSlateBrush[Name];
		delete(DeleteBrush);
		CustomFSlateBrush.Remove(Name);
	}
	CustomFSlateBrush.Add(Name, SlateBrush);
}

FSlateBrush* ListUIStyle::GetTempImage(FString Path, const FName Name, ESlateBrushDrawType::Type InDrawType, const FMargin& InMargin, ESlateBrushTileType::Type InTiling, ESlateBrushImageType::Type InImageType, const FVector2D& InImageSize, const FSlateColor& InTint)
{
	UTexture2D* GridTexture = LoadObject<UTexture2D>(nullptr, *Path, nullptr, LOAD_None, nullptr);
	GridTexture->AddToRoot(); //防止资源被释放
	FSlateBrush* SlateBrush = new FSlateBrush();
	SlateBrush->SetResourceObject(GridTexture); //资源
	SlateBrush->SetImageSize(InImageSize); //尺寸
	SlateBrush->TintColor = InTint; //颜色
	SlateBrush->Tiling = InTiling; //平铺类型
	SlateBrush->DrawAs = InDrawType; //
	SlateBrush->Margin = InMargin; //对应的平铺边距
	return SlateBrush;
}

void ListUIStyle::InitFont()
{
	CustomFont.Empty();
	AddFont("Font'/Game/ListLibraryUI/front/Alibaba-PuHuiTi-Regular_Font.Alibaba-PuHuiTi-Regular_Font'", "AlibabaRegular");
	AddFont("Font'/Game/ListLibraryUI/front/Alibaba-PuHuiTi-Medium_Font.Alibaba-PuHuiTi-Medium_Font'", "AlibabaBold");
	/*AddFont("Font'/Game/ListLibraryUI/front/MiSansBold_Font.MiSansBold_Font'", "MiSansBold");
	AddFont("Font'/Game/ListLibraryUI/front/MiSansRegular_Font.MiSansRegular_Font'", "MiSansRegular");
	AddFont("Font'/Game/ListLibraryUI/front/SongTiBold_Font.SongTiBold_Font'", "SongTiBold");
	AddFont("Font'/Game/ListLibraryUI/front/SongTiRegular_Font.SongTiRegular_Font'", "SongTiRegular");
	AddFont("Font'/Game/ListLibraryUI/front/WRYHBold_Font.WRYHBold_Font'", "WRYHBold");
	AddFont("Font'/Game/ListLibraryUI/front/WRYHRegular_Font.WRYHRegular_Font'", "WRYHRegular");*/
	InitFSlateFontInfo();
}

void ListUIStyle::AddFont(FString FontPath, FString FontName)
{
	ConstructorHelpers::FObjectFinder<UFont> FontObj(*FontPath);
	if (FontObj.Object)
	{
		UFont* Font = Cast<UFont>(FontObj.Object);
		Font->AddToRoot(); //防止资源被释放
		CustomFont.Add(FontName, Font);
	}
}

FSlateBrush* ListUIStyle::GetImage(FString ImageName)
{
	if (CustomFSlateBrush.Contains(ImageName))
	{
		return CustomFSlateBrush[ImageName];
	}
	else
	{
		return nullptr;
	}
}

FSlateFontInfo ListUIStyle::GetFont(FString FontName, uint16 size)
{
	if (CustomFont.Contains(FontName))
	{
		return FSlateFontInfo(CustomFont[FontName], size);
	}
	else //获取系统字体
	{
		return FCoreStyle::GetDefaultFontStyle(*FontName, size);
	}
}

void ListUIStyle::InitFSlateFontInfo()
{
	CustomSlateFontInfo.Empty();
	AddFSlateFontInfo("AlibabaRegular_9_000000A6");
	AddFSlateFontInfo("AlibabaRegular_9_000000D9");
	AddFSlateFontInfo("AlibabaRegular_10_000000c");
	AddFSlateFontInfo("AlibabaRegular_10_000000D9");
	AddFSlateFontInfo("AlibabaRegular_10_000000FF");
	AddFSlateFontInfo("AlibabaRegular_10_FFFFFFFF");
	AddFSlateFontInfo("AlibabaRegular_11_000000A6");
	AddFSlateFontInfo("AlibabaRegular_11_000000D9");
	AddFSlateFontInfo("AlibabaRegular_11_FFFFFFFF");
	AddFSlateFontInfo("AlibabaRegular_11_0070FDFF");
	AddFSlateFontInfo("AlibabaRegular_12_000000A6");
	AddFSlateFontInfo("AlibabaRegular_12_000000D9");
	AddFSlateFontInfo("AlibabaRegular_13_000000A6");
	AddFSlateFontInfo("AlibabaRegular_13_000000D9");
	AddFSlateFontInfo("AlibabaRegular_20_000000D9");
	AddFSlateFontInfo("AlibabaRegular_20_FFFFFFD9");
	AddFSlateFontInfo("AlibabaBold_10_FFF00FFF");
	AddFSlateFontInfo("AlibabaBold_10_FFFFFFFF");
	AddFSlateFontInfo("AlibabaBold_10_000000D9");
	AddFSlateFontInfo("AlibabaBold_11_FFFFFFFF");
	AddFSlateFontInfo("AlibabaBold_11_0072FDFF");
	AddFSlateFontInfo("AlibabaBold_12_000000D9");
	AddFSlateFontInfo("AlibabaBold_13_00000073");
	AddFSlateFontInfo("AlibabaBold_13_000000D9");
	AddFSlateFontInfo("AlibabaBold_13_00A3FAA6");
	AddFSlateFontInfo("AlibabaBold_14_000000D9");
	AddFSlateFontInfo("AlibabaBold_14_000000FF");
	AddFSlateFontInfo("AlibabaBold_16_000000D9");
	AddFSlateFontInfo("AlibabaBold_20_FFFFFFFF");
}

void ListUIStyle::AddFSlateFontInfo(FString FontStyleName)
{
	TArray<FString> Values;
	FontStyleName.ParseIntoArray(Values,TEXT("_"));
	if (Values.Num() == 3)
	{
		FString FontName = Values[0];
		uint16 size = FCString::Atoi(*Values[1]);
		FString Color = Values[2];
		if (Color.Len() == 8)
		{
			FTextBlockStyle* NewTextBlockStyle = new FTextBlockStyle();
			NewTextBlockStyle->SetFont(GetFont(FontName, size))
			                 .SetColorAndOpacity(FLinearColor(FColor::FromHex(Values[2])));
			CustomSlateFontInfo.Add(FontStyleName.ToLower(), NewTextBlockStyle);
		}
	}
}

FTextBlockStyle* ListUIStyle::GetTextBlockStyle(FString TextBlockStyleName)
{
	if (CustomSlateFontInfo.Contains(TextBlockStyleName.ToLower()))
	{
		return CustomSlateFontInfo[TextBlockStyleName.ToLower()];
	}
	else
	{
		AddFSlateFontInfo(TextBlockStyleName);
		if (CustomSlateFontInfo.Contains(TextBlockStyleName.ToLower()))
		{
			return CustomSlateFontInfo[TextBlockStyleName.ToLower()];
		}
		return nullptr;
	}
}

bool ListUIStyle::UpdateTextBlockStyle(FString TextBlockStyleName, FTextBlockStyle* TextBlockStyle)
{
	if (CustomSlateFontInfo.Contains(TextBlockStyleName.ToLower()))
	{
		CustomSlateFontInfo[TextBlockStyleName.ToLower()] = TextBlockStyle;
		return true;
	}
	return false;
}

FName ListUIStyle::GetStyleSetName()
{
	static FName SlateSetName(TEXT("ListUIStyle"));
	return SlateSetName;
}

void ListUIStyle::ShutDown()
{
	//FSlateStyleRegistry::UnRegisterSlateStyle(*StyleInstance);
	//ensure(StyleInstance.IsUnique());
	//StyleInstance.Reset();
}

const ISlateStyle& ListUIStyle::Get()
{
	return *StyleInstance;
}

TSharedRef<FSlateStyleSet> ListUIStyle::Create()
{
	TSharedRef<FSlateStyleSet> StyleRef = FSlateGameResources::New(ListUIStyle::GetStyleSetName(),
	                                                               "/Game/ListLibraryUI/Style", "/Game/ListLibraryUI/Style");
	return StyleRef;
}
